"""MySQL 数据操作类，所有需要通过 MySQL 访问数据的事务都需要通过这个类."""

import configparser
import datetime
from typing import List

import mysql.connector
from mysql.connector import Error

from src.git_log_import.models.account import Account
from src.git_log_import.models.commit_log import CommitLog
from src.git_log_import.models.repository import Repository
from src.git_log_import.models.transmission_log import TransmissionLog


class DBOperator:
    """MySQL 数据操作类，所有需要通过 MySQL 访问数据的事务都需要通过这个类."""

    def __init__(self):
        """初始化数据库连接配置."""
        self.config = configparser.ConfigParser()
        with open("config.ini", "r", encoding="utf-8") as f:
            self.config.read_file(f)

        db_section = self.config["database"]
        self.db_host = db_section["host"]
        self.db_port = db_section["port"]
        self.db_user = db_section["user"]
        self.db_password = db_section["password"]
        self.db_name = db_section["database"]

        self.build_connection()

    def insert_accounts(self, accounts: List[Account]) -> bool:
        """插入账户列表到数据库."""
        try:
            cursor = self.conn.cursor()

            insert_query = """
            INSERT INTO account
            (id, git_instance, engineer_id, username, acct_fullname, email, state, created_at, last_activity_on, updated_at)
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
            ON DUPLICATE KEY UPDATE
            username = VALUES(username),
            acct_fullname = VALUES(acct_fullname),
            email = VALUES(email),
            state = VALUES(state),
            created_at = VALUES(created_at),
            last_activity_on = VALUES(last_activity_on),
            updated_at = VALUES(updated_at)
            """

            data = []
            for account in accounts:
                updated_at = (
                    account.updated_at
                    if account.updated_at
                    else datetime.datetime.now()
                )
                data.append(
                    (
                        account.id,
                        account.git_instance,
                        account.engineer_id,
                        account.username,
                        account.acct_fullname,
                        account.email,
                        account.state,
                        account.created_at,
                        account.last_activity_on,
                        updated_at,
                    )
                )

            if data:
                cursor.executemany(insert_query, data)

            self.conn.commit()
            cursor.close()
            return True
        except Error as e:
            print(f"Error inserting accounts: {e}")
            return False

    def insert_repositories(self, repositories: List[Repository]) -> bool:
        """插入仓库列表到数据库."""
        try:
            cursor = self.conn.cursor()

            insert_query = """
            INSERT INTO repository
            (id, git_instance, project_id, repo_fullname, path_with_namespace, description, created_at, web_url, updated_at)
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
            ON DUPLICATE KEY UPDATE
            git_instance = VALUES(git_instance),
            project_id = VALUES(project_id),
            repo_fullname = VALUES(repo_fullname),
            path_with_namespace = VALUES(path_with_namespace),
            description = VALUES(description),
            created_at = VALUES(created_at),
            web_url = VALUES(web_url),
            updated_at = VALUES(updated_at)
            """

            data = []
            for repo in repositories:
                updated_at = (
                    repo.updated_at if repo.updated_at else datetime.datetime.now()
                )
                data.append(
                    (
                        repo.id,
                        repo.git_instance,
                        repo.project_id,
                        repo.repo_fullname,
                        repo.path_with_namespace,
                        repo.description,
                        repo.created_at,
                        repo.web_url,
                        updated_at,
                    )
                )

            if data:
                cursor.executemany(insert_query, data)

            self.conn.commit()
            cursor.close()
            return True
        except Error as e:
            print(f"Error inserting repositories: {e}")
            return False

    def insert_commit_logs(self, commit_logs: List[CommitLog]) -> bool:
        """插入 commits 日志到数据库，返回成功/失败."""
        try:
            cursor = self.conn.cursor()

            insert_query = """
            INSERT INTO commit_log
            (id, git_instance, repository_id, branch_id, email, committer_fullname, created_at,
            additions, deletions, total_changes, message, web_url, commit_type, updated_at)
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
            ON DUPLICATE KEY UPDATE
            git_instance = VALUES(git_instance),
            repository_id = VALUES(repository_id),
            branch_id = VALUES(branch_id),
            email = VALUES(email),
            committer_fullname = VALUES(committer_fullname),
            created_at = VALUES(created_at),
            additions = VALUES(additions),
            deletions = VALUES(deletions),
            total_changes = VALUES(total_changes),
            message = VALUES(message),
            web_url = VALUES(web_url),
            commit_type = VALUES(commit_type),
            updated_at = VALUES(updated_at)
            """

            data = []
            for commit in commit_logs:
                updated_at = (
                    commit.updated_at if commit.updated_at else datetime.datetime.now()
                )
                data.append(
                    (
                        commit.id,
                        commit.git_instance,
                        commit.repository_id,
                        commit.branch_id,
                        commit.email,
                        commit.committer_fullname,
                        commit.created_at,
                        commit.additions,
                        commit.deletions,
                        commit.total_changes,
                        commit.message,
                        commit.web_url,
                        commit.commit_type,
                        updated_at,
                    )
                )

            if data:
                cursor.executemany(insert_query, data)

            self.conn.commit()
            cursor.close()
            return True
        except Error as e:
            print(f"Error inserting commit logs: {e}")
            return False

    def log_transmission(self, transmission_log: TransmissionLog) -> bool:
        """记录传输日志到数据库，返回成功/失败."""
        try:
            cursor = self.conn.cursor()

            insert_query = """
            INSERT INTO transmission_log
            (id, gitlab_instance, repository_id, start_time, end_time, status,
            last_synced_at, last_synced_sha, transferred_count, error_message, updated_at)
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
            ON DUPLICATE KEY UPDATE
            gitlab_instance = VALUES(gitlab_instance),
            repository_id = VALUES(repository_id),
            start_time = VALUES(start_time),
            end_time = VALUES(end_time),
            status = VALUES(status),
            last_synced_at = VALUES(last_synced_at),
            last_synced_sha = VALUES(last_synced_sha),
            transferred_count = VALUES(transferred_count),
            error_message = VALUES(error_message),
            updated_at = VALUES(updated_at)
            """

            updated_at = (
                transmission_log.updated_at
                if transmission_log.updated_at
                else datetime.datetime.now()
            )
            data = (
                transmission_log.id,
                transmission_log.gitlab_instance,
                transmission_log.repository_id,
                transmission_log.start_time,
                transmission_log.end_time,
                transmission_log.status,
                transmission_log.last_synced_at,
                transmission_log.last_synced_sha,
                transmission_log.transferred_count,
                transmission_log.error_message,
                updated_at,
            )

            cursor.execute(insert_query, data)

            self.conn.commit()
            cursor.close()
            return True
        except Error as e:
            print(f"Error logging transmission: {e}")
            return False

    def build_connection(self) -> bool:
        """测试数据库连接，如果成功返回 True，否则返回 False."""
        try:
            self.conn = mysql.connector.connect(
                host=self.db_host,
                port=int(self.db_port),
                database=self.db_name,
                user=self.db_user,
                password=self.db_password,
            )
            if self.conn.is_connected():
                print("Database connection successful!")
                return True
        except Error as e:
            print(f"Database connection failed: {e}")
            return False

    def test_connection(self) -> bool:
        """测试数据库连接."""
        return self.build_connection()

    def __del__(self):
        """在对象销毁时关闭数据库连接."""
        if hasattr(self, "conn") and self.conn and self.conn.is_connected():
            self.conn.close()
            print("Database connection closed.")

    # 其他可能的方法，根据需要添加
